package zarzadcyZdarzen;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.*;

/**
 * Klasa bezpośrednio obsługująca sieć, wruca komunikaty przychodzące od serwera
 * do kolejki komunikatów wejściowych, wysyła komunikaty pobrane z kolejki komunikatów wejściowych
 * @author Konrad Sobczak
 * @author Kamil Nowak
 */

public class SendingAdapter implements Runnable{
	 
	Socket gniazdo=null;
	BlockingQueue<String> in;
	BlockingQueue<String> out;
	InputStreamReader inStream;
	OutputStream outStream;
	PrintWriter strumien_wyjsciowy;
	BufferedReader inread;
	AtomicBoolean koniec=new AtomicBoolean();
	
	/**
	 * Tworzy obiekt SendingAdaptera
	 * @param s - już otwarte gniazdo poprzez które będziemy się komunikować z serwerem
	 * @param in - kolejka komunikatów wejściowych
	 * @param out - kolejka komunikatów wyjściowych
	 */
	public SendingAdapter(Socket s, BlockingQueue<String> in, BlockingQueue<String> out){
		koniec.set(true);
		gniazdo=s;
		this.in = in;
		this.out = out;
		try{ 
			
			inStream = new InputStreamReader(gniazdo.getInputStream(),Charset.forName("ISO-8859-2"));	
			inread =  new BufferedReader(inStream);
				
			
		//inStream = new InputStreamReader(gniazdo.getInputStream());	
		//inread =  new BufferedReader(inStream);
		 //outStream = gniazdo.getOutputStream();
			strumien_wyjsciowy = new PrintWriter(new OutputStreamWriter(gniazdo.getOutputStream(),Charset.forName("ISO-8859-2")),true);
		}
		catch(IOException e){
			System.out.println("wywalilem sie");
		}
		//strumien_wyjsciowy = new PrintWriter(outStream,true);	
		
	}
	
	/**
	 * Wywołanie metody kończy działanie wątku
	 *
	 */
	public void set_koniec(){
		koniec.set(false);
	}
	
	/** 
	 * Wywołanie metody powoduje definitywne zakończenie połączenia sieciowego
	 *
	 */
	public void zamknijPolaczenie(){
		if(gniazdo!=null){
			try{
			gniazdo.close();
			}
			catch(IOException e){
				
			}
		}
	}
	
	/** 
	 * Pętla sprawdzająca warunek końca, sprawdza czy w strumieniu wejściowym coś jest, jeśli tak - wrzuca to
	 * do kolejki komunikatów wejściowych. Następnie podnosi element z kolejki komunikatów wyjściowych - jeśli
	 * jest różny od null - wysyła ten komunikat do serwera.
	 */
	public void run(){
		String a;
		
		try{	
			try{
				while(koniec.get()==true){	
					if((a=out.poll())!=null)
						strumien_wyjsciowy.println(a);
					if(inread.ready()){
						a=inread.readLine();
						System.out.println(a);
						in.add(a);
					}
					Thread.sleep(50);
				}
			}
			finally{
				gniazdo.close();
			}
		}
		catch(Exception e){
			
		}
	
		
	}
}